gusucode.com > VC++ 图像处理(灰度变换、图像合成、羽化、中心法校正)-源码 > VC++ 图像处理(灰度变换、图像合成、羽化、中心法校正)-源码程序/code/VCIPH/VCIPHView.cpp

    //Download by http://www.NewXing.com
// VCIPHView.cpp : implementation of the CVCIPHView class
//

#include "stdafx.h"
#include "VCIPH.h"

#include "VCIPHDoc.h"
#include "VCIPHView.h"

int  MEASURE     =0;
int  LINEDISTANCE=0;
int  AREAFORM    =0;
int  type;

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

void FeatherArea(CDibs* pDibs,int n,int flag);
void FeatherAreaL(CDibs* pDibs,int n,int flag);
void FeatherAreaE(CDibs* pDibs,int n,int flag);
int  InnerDistance(BYTE *buf,int Dx,int Dy,
			   struct TAB *tab,int num,int n);
int  OuterDistance(BYTE *buf,int Dx,int Dy,
			   struct TAB *tab,int num,int n);
void ColorToGray(BYTE *buf0,int ppl0,BYTE *buf1,int ppl1,int Dy);
void CopyLineTableDataA(BYTE **list,struct TAB *tab,
						int num,int x,int y,int color);
         
/////////////////////////////////////////////////////////////////////////////
// CVCIPHView

IMPLEMENT_DYNCREATE(CVCIPHView, CScrollView)

BEGIN_MESSAGE_MAP(CVCIPHView, CScrollView)
	//{{AFX_MSG_MAP(CVCIPHView)
	ON_COMMAND(ID_OPEN_ADD_IMAGE, OnOpenAddImage)
	ON_UPDATE_COMMAND_UI(ID_OPEN_ADD_IMAGE, OnUpdateOpenAddImage)
	ON_COMMAND(ID_ALPHA_BLEND, OnAlphaBlend)
	ON_UPDATE_COMMAND_UI(ID_ALPHA_BLEND, OnUpdateAlphaBlend)
	ON_COMMAND(ID_IMAGE_BLEND, OnImageBlend)
	ON_UPDATE_COMMAND_UI(ID_IMAGE_BLEND, OnUpdateImageBlend)
	ON_COMMAND(ID_BIT_BLT, OnBitBlt)
	ON_UPDATE_COMMAND_UI(ID_BIT_BLT, OnUpdateBitBlt)
	ON_COMMAND(ID_IMAGE_BIT_BLT, OnImageBitBlt)
	ON_UPDATE_COMMAND_UI(ID_IMAGE_BIT_BLT, OnUpdateImageBitBlt)
	ON_COMMAND(ID_CIRCLE_MASK, OnCircleMask)
	ON_UPDATE_COMMAND_UI(ID_CIRCLE_MASK, OnUpdateCircleMask)
	ON_COMMAND(ID_CREATE_MASK, OnCreateMask)
	ON_UPDATE_COMMAND_UI(ID_CREATE_MASK, OnUpdateCreateMask)
	ON_COMMAND(ID_IMAGE_BLEND_A, OnImageBlendA)
	ON_UPDATE_COMMAND_UI(ID_IMAGE_BLEND_A, OnUpdateImageBlendA)
	ON_COMMAND(ID_REFRESH, OnRefresh)
	ON_COMMAND(ID_MODIFY_PALETTE, OnModifyPalette)
	ON_COMMAND(ID_MODIFY_PIXEL, OnModifyPixel)
	ON_COMMAND(ID_LOCK_TABLE, OnLockTable)
	ON_UPDATE_COMMAND_UI(ID_MODIFY_PALETTE, OnUpdateModifyPalette)
	ON_UPDATE_COMMAND_UI(ID_MODIFY_PIXEL, OnUpdateModifyPixel)
	ON_UPDATE_COMMAND_UI(ID_LOCK_TABLE, OnUpdateLockTable)
	ON_COMMAND(ID_MASK_BLEND, OnMaskBlend)
	ON_UPDATE_COMMAND_UI(ID_MASK_BLEND, OnUpdateMaskBlend)
	ON_COMMAND(ID_CREATE_MASKA, OnCreateMaska)
	ON_UPDATE_COMMAND_UI(ID_CREATE_MASKA, OnUpdateCreateMaska)
	ON_COMMAND(ID_CREATE_MASKB, OnCreateMaskb)
	ON_UPDATE_COMMAND_UI(ID_CREATE_MASKB, OnUpdateCreateMaskb)
	ON_COMMAND(ID_FEATHER_AREA, OnFeatherArea)
	ON_UPDATE_COMMAND_UI(ID_FEATHER_AREA, OnUpdateFeatherArea)
	ON_COMMAND(ID_FEATHER_BLEND_B, OnFeatherBlendB)
	ON_UPDATE_COMMAND_UI(ID_FEATHER_BLEND_B, OnUpdateFeatherBlendB)
	ON_COMMAND(ID_FEATHER_BLEND_A, OnFeatherBlendA)
	ON_UPDATE_COMMAND_UI(ID_FEATHER_BLEND_A, OnUpdateFeatherBlendA)
	ON_COMMAND(ID_DISTANCE, OnDistance)
	ON_UPDATE_COMMAND_UI(ID_DISTANCE, OnUpdateDistance)
	ON_COMMAND(ID_OUTER_DISTANCE, OnOuterDistance)
	ON_UPDATE_COMMAND_UI(ID_OUTER_DISTANCE, OnUpdateOuterDistance)
	ON_COMMAND(ID_SETUP, OnSetup)
	ON_COMMAND(ID_OUTER_DISTANCEA, OnOuterDistancea)
	ON_UPDATE_COMMAND_UI(ID_OUTER_DISTANCEA, OnUpdateOuterDistancea)
	ON_COMMAND(ID_DISTANCEA, OnDistancea)
	ON_UPDATE_COMMAND_UI(ID_DISTANCEA, OnUpdateDistancea)
	ON_COMMAND(ID_DISTANCEB, OnDistanceb)
	ON_COMMAND(ID_DISTANCEC, OnDistancec)
	ON_COMMAND(ID_DISTANCED, OnDistanced)
	ON_COMMAND(ID_DISTANCEE, OnDistancee)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CVCIPHView construction/destruction

CVCIPHView::CVCIPHView()
{
	// TODO: add construction code here
	pSaveDibs=NULL;
	pWorkDibs=NULL;
	pMaskDibs=NULL;
	pAddDibs =NULL;
	pTempDibs=NULL;
	pTmp2Dibs=NULL;
}

CVCIPHView::~CVCIPHView()
{
 	DeleteDibs(pSaveDibs);
 	DeleteDibs(pWorkDibs);
 	DeleteDibs(pMaskDibs);
 	DeleteDibs(pAddDibs);
 	DeleteDibs(pTempDibs);
 	DeleteDibs(pTmp2Dibs);
}

BOOL CVCIPHView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CScrollView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CVCIPHView drawing

void CVCIPHView::OnDraw(CDC* pDC)
{
	CVCIPHDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	if (pDoc->pDibs!=NULL)	{	
		struct IMAGE_PARAMENTS P;
   		HDC    hSrcDC;
		CDC	   *pSrcDC;

		GetImageParaments(&P,pDoc->pDibs);

		if (pSaveDibs==NULL) {
			pSaveDibs = CopyDibs(pDoc->pDibs);
			pWorkDibs = CopyDibs(pSaveDibs);
		}

 		hSrcDC = GetMemDC(pWorkDibs->hBitmap);
 		pSrcDC=CDC::FromHandle(hSrcDC);
   		pDC->BitBlt(0,0,P.wid,P.hei,pSrcDC,0,0,SRCCOPY);
   		ReleaseMemDC(hSrcDC); 
	}	
}

void CVCIPHView::OnInitialUpdate()
{
	CScrollView::OnInitialUpdate();

	CSize sizeTotal;
	// TODO: calculate the total size of this view
	CVCIPHDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

 	sizeTotal = CSize(pDoc->pDibs->wid,pDoc->pDibs->hei);
 	SetScrollSizes(MM_TEXT, sizeTotal);

	GetParentFrame()->RecalcLayout();
	ResizeParentToFit();
}

/////////////////////////////////////////////////////////////////////////////
// CVCIPHView diagnostics

#ifdef _DEBUG
void CVCIPHView::AssertValid() const
{
	CScrollView::AssertValid();
}

void CVCIPHView::Dump(CDumpContext& dc) const
{
	CScrollView::Dump(dc);
}

CVCIPHDoc* CVCIPHView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CVCIPHDoc)));
	return (CVCIPHDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CVCIPHView message handlers

void CVCIPHView::OnUpdateOpenAddImage(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable(pSaveDibs!=NULL);
}

void CVCIPHView::OnUpdateOpenMaskImage(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable(pSaveDibs!=NULL);
}

void CVCIPHView::OnUpdateCircleMask(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable(true);
}

void CVCIPHView::OnUpdateCreateMask(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable(pAddDibs!=NULL);
}

void CVCIPHView::OnUpdateCreateMaska(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable(pAddDibs!=NULL);
}

void CVCIPHView::OnUpdateCreateMaskb(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable(pAddDibs!=NULL);
}

void CVCIPHView::OnUpdateAlphaBlend(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable(pAddDibs!=NULL);
}

void CVCIPHView::OnUpdateImageBlendA(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable(pAddDibs!=NULL);
}

void CVCIPHView::OnUpdateImageBlend(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable(pAddDibs!=NULL);
}

void CVCIPHView::OnUpdateBitBlt(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable((pMaskDibs!=NULL)&&(pAddDibs!=NULL)&&
		(pMaskDibs->bits==1));
}

void CVCIPHView::OnUpdateMaskBlend(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable((pMaskDibs!=NULL)&&(pAddDibs!=NULL)&&
		(pMaskDibs->bits==1));
}

void CVCIPHView::OnUpdateDistance(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable((pMaskDibs!=NULL)&&(pMaskDibs->bits==1));
}

void CVCIPHView::OnUpdateDistancea(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable((LINEDISTANCE==2)&&(pMaskDibs!=NULL)&&
		(pMaskDibs->bits==1));
}

void CVCIPHView::OnUpdateOuterDistance(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable((pMaskDibs!=NULL)&&
		(pMaskDibs->bits==1));
}

void CVCIPHView::OnUpdateOuterDistancea(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable((LINEDISTANCE==2)&&(pMaskDibs!=NULL)&&
		(pMaskDibs->bits==1));
}

void CVCIPHView::OnUpdateFeatherArea(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable((pMaskDibs!=NULL)&&(pAddDibs!=NULL)&&
		(pMaskDibs->bits==1));
}

void CVCIPHView::OnUpdateFeatherBlendA(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable((pMaskDibs!=NULL)&&(pAddDibs!=NULL)&&
		(pMaskDibs->bits==1));
}

void CVCIPHView::OnUpdateFeatherBlendB(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable((pMaskDibs!=NULL)&&(pAddDibs!=NULL)&&
		(pMaskDibs->bits==1));
}

void CVCIPHView::OnUpdateImageBitBlt(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable((pMaskDibs!=NULL)&&(pAddDibs!=NULL)&&
		(pMaskDibs->bits==8));
}

void CVCIPHView::OnUpdateModifyPalette(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable((pWorkDibs!=NULL)&&(pWorkDibs->bits==8));
}

void CVCIPHView::OnUpdateModifyPixel(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable((pWorkDibs!=NULL)&&(pWorkDibs->bits==8));
}

void CVCIPHView::OnUpdateLockTable(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable((pWorkDibs!=NULL)&&(pWorkDibs->bits==8));
}

//---------------------------------------------------------

void CVCIPHView::OnRefresh() 
{
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);

	Invalidate();
}

BOOL CVCIPHView::LoadAddBMP(LPCTSTR lpszPathName)
{
	BITMAPFILEHEADER Bfh; 
    BITMAPINFOHEADER Bmih;
	FILE  *fp;
	int	  wid,hei,bits,pals,size;
	RGBQUAD ColorTab[256];
 
	fp=fopen(lpszPathName,"rb");
	if (fp==NULL) return FALSE;

	fread(&Bfh,sizeof(BITMAPFILEHEADER),1,fp);  //  读入位图文件头
 	fread(&Bmih,sizeof(BITMAPINFOHEADER),1,fp); //  读入位图信息头

	wid =Bmih.biWidth;                      //  得图像主要参数
	hei =Bmih.biHeight;
	bits=Bmih.biBitCount;
 
	DeleteDibs(pAddDibs);
	pAddDibs = CreateDibs(wid,hei,bits);    //  建立位图
	pals=(Bfh.bfOffBits-sizeof(BITMAPFILEHEADER)-
		        sizeof(BITMAPINFOHEADER));  //  计算调色板尺寸
    if (pals) {
  		fread(ColorTab,pals,1,fp);          //  读入调色板数据
		pAddDibs->setallpalette(ColorTab);  //  设置位图调色板
	}
 	size=(wid*bits+31)/32*4*hei;            //  计算像素字节数
 
	fseek(fp,Bfh.bfOffBits,SEEK_SET);       //  像素数据定位
	fread(pAddDibs->pBits,size,1,fp);       //  读入像素数据
	fclose(fp);  

   	return TRUE;
}

BOOL CVCIPHView::LoadMaskBMP(LPCTSTR lpszPathName)
{
	BITMAPFILEHEADER Bfh; 
    BITMAPINFOHEADER Bmih;
	FILE  *fp;
	int	  wid,hei,bits,pals,size;
	RGBQUAD ColorTab[256];
 
	fp=fopen(lpszPathName,"rb");
	if (fp==NULL) return FALSE;

	fread(&Bfh,sizeof(BITMAPFILEHEADER),1,fp);  //  读入位图文件头
 	fread(&Bmih,sizeof(BITMAPINFOHEADER),1,fp); //  读入位图信息头

	wid =Bmih.biWidth;                      //  得图像主要参数
	hei =Bmih.biHeight;
	bits=Bmih.biBitCount;
	if (bits>1) {
		fclose(fp);  
		return FALSE;
	}
 
	DeleteDibs(pMaskDibs);
	pMaskDibs = CreateDibs(wid,hei,bits);   //  建立位图
	pals=(Bfh.bfOffBits-sizeof(BITMAPFILEHEADER)-
		        sizeof(BITMAPINFOHEADER));  //  计算调色板尺寸
    if (pals) {
  		fread(ColorTab,pals,1,fp);          //  读入调色板数据
		pMaskDibs->setallpalette(ColorTab); //  设置位图调色板
	}
 	size=(wid*bits+31)/32*4*hei;            //  计算像素字节数
 
	fseek(fp,Bfh.bfOffBits,SEEK_SET);       //  像素数据定位
	fread(pMaskDibs->pBits,size,1,fp);      //  读入像素数据
	fclose(fp);  

   	return TRUE;
}

void CVCIPHView::OnOpenAddImage() 
{
    CString csBMP="BMP Files(*.BMP)|*.BMP|";
    CString csFilter=csBMP;
	BOOL	bl;

	CFileDialog FileDlg(TRUE,NULL,NULL,OFN_HIDEREADONLY,csFilter);
	
	if (FileDlg.DoModal()==IDOK ) {
		bl=LoadAddBMP(FileDlg.GetPathName());
	}

	if (bl==TRUE) {
		DeleteDibs(pWorkDibs);
		pWorkDibs=CopyDibs(pAddDibs);
		Invalidate();
	}
}

void CVCIPHView::OnOpenMaskImage() 
{
    CString csBMP="BMP Files(*.BMP)|*.BMP|";
    CString csFilter=csBMP;
	BOOL	bl;

	CFileDialog FileDlg(TRUE,NULL,NULL,OFN_HIDEREADONLY,csFilter);
	
	if (FileDlg.DoModal()==IDOK ) {
		bl=LoadMaskBMP(FileDlg.GetPathName());
	}

	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pMaskDibs);
	Invalidate();
}

//---------------------------------------------------------
//   运行程序
void CVCIPHView::ModifyPalette0()          //  修改调色板
{
    struct IMAGE_PARAMENTS P;
	int    pg[256],T_gray[256];
  
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);

    GetImageParaments(&P,pWorkDibs);
 	Histog(P.pBits,pg,P.ppl,P.hei);
	GT_Equal(pg,T_gray);

 	pWorkDibs->SetGTPalette(T_gray);
 
	Invalidate();
}

void CVCIPHView::ModifyPixel0()            //  BitBlt 操作
{
    struct IMAGE_PARAMENTS P;
	int    pg[256],T_gray[256];
	HDC    hDCw,hDCt;
  
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);

    GetImageParaments(&P,pWorkDibs);
 	Histog(P.pBits,pg,P.ppl,P.hei);
	GT_Equal(pg,T_gray);

  	pWorkDibs->SetGTPalette(T_gray);
	DeleteDibs(pTempDibs);
	pTempDibs=CreateDibs(P.ppl,P.hei,8);
	pTempDibs->SetGrayPalette();
  	hDCw = GetMemDC(pWorkDibs->hBitmap);
	hDCt = GetMemDC(pTempDibs->hBitmap);
	BitBlt(hDCt,0,0,P.ppl,P.hei,hDCw,0,0,SRCCOPY);
	ReleaseMemDC(hDCw);
   	ReleaseMemDC(hDCt);
 
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pTempDibs);
}

void CVCIPHView::LockTable0()              //  查找表法
{
    struct IMAGE_PARAMENTS P;
	int    i,pg[256],T_gray[256];
  	BYTE   *buf;
 
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);

    GetImageParaments(&P,pWorkDibs);
 	Histog(P.pBits,pg,P.ppl,P.hei);
	GT_Equal(pg,T_gray);

 	buf=P.pBits;
 	for (i=0;i<P.size;i++,buf++) {                                 
		(*buf)=T_gray[(*buf)];      
	}
}

void CVCIPHView::AlphaBlend0()             //  AlphaBlend
{
	struct IMAGE_PARAMENTS Pw,Pa;
	HDC  hSrcDC,hTrcDC;
	BLENDFUNCTION rBlendProps;
	int  Alpha,wid,hei;
  
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);

	GetImageParaments(&Pw,pWorkDibs);
	GetImageParaments(&Pa,pAddDibs);
 	wid=min(Pw.wid,Pa.wid);
	hei=min(Pw.hei,Pa.hei);

	Alpha=100;
 	rBlendProps.BlendOp = AC_SRC_OVER;
	rBlendProps.BlendFlags = 0;
	rBlendProps.SourceConstantAlpha=Alpha;
	rBlendProps.AlphaFormat = 0;     
 	hSrcDC = GetMemDC(pAddDibs->hBitmap);
	hTrcDC = GetMemDC(pWorkDibs->hBitmap);
 	AlphaBlend(hTrcDC,0,0,wid,hei,
			hSrcDC,0,0,wid,hei,rBlendProps);
   	ReleaseMemDC(hSrcDC);
   	ReleaseMemDC(hTrcDC);
}

void CVCIPHView::ImageBlendA0()            //  线性叠加
{
	struct IMAGE_PARAMENTS Pw,Pa,Pt;
	HDC  hDCa,hDCt;
	BYTE *bufw,*bufa;
	int  i,Alpha;
  
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);
	GetImageParaments(&Pw,pWorkDibs);
	GetImageParaments(&Pa,pAddDibs);
	if ((Pw.wid!=Pa.wid)||(Pw.hei!=Pa.hei)) {
		MessageBox("图像尺寸不一致!","警告",MB_OK);
		return;
	}
  
	Alpha=100;
	bufw=Pw.pBits;		bufa=Pa.pBits;
 	if (Pw.bits!=Pa.bits) {
		DeleteDibs(pTempDibs);
		pTempDibs=CreateDibs(Pw.wid,Pw.hei,Pw.bits);
		if (Pw.bits==8)
			pTempDibs->SetGrayPalette();
		GetImageParaments(&Pt,pTempDibs);
 		hDCa = GetMemDC(pAddDibs->hBitmap);
  		hDCt = GetMemDC(pTempDibs->hBitmap);
  		BitBlt(hDCt,0,0,Pw.ppl,Pw.hei,hDCa,0,0,SRCCOPY);
    	ReleaseMemDC(hDCa);
   		ReleaseMemDC(hDCt);
		bufa=Pt.pBits;
	}
   	for (i=0;i<Pw.size;i++) {
		(*bufw)=((Alpha*(*bufa)+(255-Alpha)*(*bufw))>>8)&0xff;
		bufw++;		bufa++;
	}
}

void CVCIPHView::ImageBlend0()             //  查表叠加
{
	struct IMAGE_PARAMENTS Pw,Pa,Pt;
	HDC  hDCa,hDCt;
	BYTE *bufw,*bufa,TabS[256],TabD[256];
	int  i,Alpha;
  
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);
	GetImageParaments(&Pw,pWorkDibs);
	GetImageParaments(&Pa,pAddDibs);
	if ((Pw.wid!=Pa.wid)||(Pw.hei!=Pa.hei)) {
		MessageBox("图像尺寸不一致!","警告",MB_OK);
		return;
	}
 
	Alpha=100;
	bufw=Pw.pBits;		bufa=Pa.pBits;
 	if (Pw.bits!=Pa.bits) {
		DeleteDibs(pTempDibs);
		pTempDibs=CreateDibs(Pw.wid,Pw.hei,Pw.bits);
		if (Pw.bits==8)
			pTempDibs->SetGrayPalette();
		GetImageParaments(&Pt,pTempDibs);
 		hDCa = GetMemDC(pAddDibs->hBitmap);
  		hDCt = GetMemDC(pTempDibs->hBitmap);
  		BitBlt(hDCt,0,0,Pw.ppl,Pw.hei,hDCa,0,0,SRCCOPY);
    	ReleaseMemDC(hDCa);
   		ReleaseMemDC(hDCt);
		bufa=Pt.pBits;
	}
	for (i=0;i<256;i++) TabS[i]=Alpha*i/255;
	for (i=0;i<256;i++) TabD[i]=i-TabS[i];
  	for (i=0;i<Pw.size;i++) {
		(*bufw)=TabS[(*bufa)]+TabD[(*bufw)];
		bufw++;		bufa++;
	}
}

void CVCIPHView::BitBlt0()                 //  5次BitBlt
{
	struct IMAGE_PARAMENTS Pw,Pa;
	HDC  hDCm,hDCt,hDCw,hDCa;
   
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);

	GetImageParaments(&Pw,pWorkDibs);
	GetImageParaments(&Pa,pAddDibs);

 	DeleteDibs(pTempDibs);
	pTempDibs=CreateDibs(Pw.wid,Pw.hei,Pw.bits);
	if (Pw.bits==8)
		pTempDibs->SetGrayPalette();
  	hDCm = GetMemDC(pMaskDibs->hBitmap);
	hDCt = GetMemDC(pTempDibs->hBitmap);
	hDCw = GetMemDC(pWorkDibs->hBitmap);
	hDCa = GetMemDC(pAddDibs->hBitmap);

	BitBlt(hDCt,0,0,Pw.wid,Pw.hei,hDCm,0,0,SRCCOPY);
 	BitBlt(hDCt,0,0,Pw.wid,Pw.hei,hDCw,0,0,SRCERASE);
  	BitBlt(hDCw,0,0,Pw.wid,Pw.hei,hDCa,0,0,SRCCOPY);
 	BitBlt(hDCw,0,0,Pw.wid,Pw.hei,hDCm,0,0,SRCAND);
 	BitBlt(hDCw,0,0,Pw.wid,Pw.hei,hDCt,0,0,SRCPAINT);

	ReleaseMemDC(hDCm);
   	ReleaseMemDC(hDCt);
   	ReleaseMemDC(hDCw);
   	ReleaseMemDC(hDCa);
}

void CVCIPHView::MaskBlend0()              //  掩模控制合成
{
	struct IMAGE_PARAMENTS Pw,Pa,Pm,Pt,P2;
	HDC  hDCm,hDCt,hDCa;
	BYTE *bufw,*bufa,*buf;
	int  i,size;
  
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);
	GetImageParaments(&Pw,pWorkDibs);
	GetImageParaments(&Pa,pAddDibs);
	GetImageParaments(&Pm,pMaskDibs);
	if ((Pw.wid!=Pa.wid)||(Pw.hei!=Pa.hei)||
		(Pm.bits!=1)) {
		MessageBox("图像尺寸不一致!","警告",MB_OK);
 		return;
	}
  
	DeleteDibs(pTmp2Dibs);
 	pTmp2Dibs=CreateDibs(Pw.wid,Pw.hei,Pw.bits);
	if (Pw.bits==8)
		pTmp2Dibs->SetGrayPalette();
	GetImageParaments(&P2,pTmp2Dibs);
 	hDCm = GetMemDC(pMaskDibs->hBitmap);
	hDCt = GetMemDC(pTmp2Dibs->hBitmap);
	BitBlt(hDCt,0,0,Pw.ppl,Pw.hei,hDCm,0,0,SRCCOPY);
	ReleaseMemDC(hDCm);
   	ReleaseMemDC(hDCt);
 
	buf =P2.pBits;		size=Pw.size;
 	bufw=Pw.pBits;		bufa=Pa.pBits;
 	if (Pw.bits!=Pa.bits) {
		DeleteDibs(pTempDibs);
		pTempDibs=CreateDibs(Pw.wid,Pw.hei,Pw.bits);
		if (Pw.bits==8)
			pTempDibs->SetGrayPalette();
		GetImageParaments(&Pt,pTempDibs);
		hDCa = GetMemDC(pAddDibs->hBitmap);
 		hDCt = GetMemDC(pTempDibs->hBitmap);
  		BitBlt(hDCt,0,0,Pw.ppl,Pw.hei,hDCa,0,0,SRCCOPY);
    	ReleaseMemDC(hDCa);
   		ReleaseMemDC(hDCt);
		bufa=Pt.pBits;
	}
   	for (i=0;i<Pw.size;i++) {
 		if (*buf++) (*bufw)=(*bufa);
 		bufw++;		bufa++;
	}
}

void CVCIPHView::ImageBitBlt0()            //  线性叠加
{
	struct IMAGE_PARAMENTS Pw,Pa,Pm,Pt,P2;
 	HDC  hDCm,hDCt,hDCa;
	BYTE *bufw,*bufa,*buf;
	int  i,Alpha;
  
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);

	GetImageParaments(&Pw,pWorkDibs);
	GetImageParaments(&Pa,pAddDibs);
	GetImageParaments(&Pm,pMaskDibs);
	if ((Pw.wid!=Pa.wid)||(Pw.hei!=Pa.hei)||
		(Pm.bits!=8)) {
		MessageBox("图像尺寸不一致!","警告",MB_OK);
 		return;
	}
	
	if (Pw.bits==24) {
		DeleteDibs(pTmp2Dibs);
 		pTmp2Dibs=CreateDibs(Pw.wid,Pw.hei,24);
		GetImageParaments(&P2,pTmp2Dibs);
 		hDCm = GetMemDC(pMaskDibs->hBitmap);
		hDCt = GetMemDC(pTmp2Dibs->hBitmap);
		BitBlt(hDCt,0,0,Pw.wid,Pw.hei,hDCm,0,0,SRCCOPY);
		ReleaseMemDC(hDCm);
   		ReleaseMemDC(hDCt);
		buf =P2.pBits;
	}
	else buf=Pm.pBits;

 	bufw=Pw.pBits;	 bufa=Pa.pBits;
	if (Pw.bits!=Pa.bits) {
		DeleteDibs(pTempDibs);
		pTempDibs=CreateDibs(Pw.wid,Pw.hei,Pw.bits);
		if (Pw.bits==8)
			pTempDibs->SetGrayPalette();
		GetImageParaments(&Pt,pTempDibs);
 		hDCa = GetMemDC(pAddDibs->hBitmap);
 		hDCt = GetMemDC(pTempDibs->hBitmap);
  		BitBlt(hDCt,0,0,Pw.ppl,Pw.hei,hDCa,0,0,SRCCOPY);
    	ReleaseMemDC(hDCa);
   		ReleaseMemDC(hDCt);
		bufa=Pt.pBits;
	}
 	Alpha=0;
  	for (i=0;i<Pw.size;i++) {
		Alpha=(*buf++);
		(*bufw)=((Alpha*(*bufa)+(255-Alpha)*(*bufw))>>8)&0xff;
		bufw++;		bufa++;
	}
}

void CVCIPHView::DistanceA(int flag) 
{
	struct IMAGE_PARAMENTS Pw,Pt;
  	HDC    hDCm,hDCt;
	struct TAB *tabA,*tabB;   
	int    numa,numb;

	tabA=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);
	tabB=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);

	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);

   	GetImageParaments(&Pw,pWorkDibs);
  	DeleteDibs(pTempDibs);
	pTempDibs=CreateDibs(Pw.ppl,Pw.hei,8);
	pTempDibs->SetGrayPalette();
   	hDCm = GetMemDC(pMaskDibs->hBitmap);
	hDCt = GetMemDC(pTempDibs->hBitmap);
	BitBlt(hDCt,0,0,Pw.ppl,Pw.hei,hDCm,0,0,SRCCOPY);
	if ((LINEDISTANCE==0)&&(flag==1)) {
  		PatBlt(hDCt,0,0,Pw.ppl,Pw.hei,DSTINVERT);
	}
 	ReleaseMemDC(hDCm);
   	ReleaseMemDC(hDCt);

	pTempDibs->SetDefaultPalette();
  	GetImageParaments(&Pt,pTempDibs);
	if (LINEDISTANCE==0) {
		Distance5(Pt.pBits,Pt.ppl,Pt.hei);
	}
	else {
 		numa=CreateTab(Pt.pBits,Pt.ppl,Pt.hei,tabA);
		if (flag==0) {
  			InnerDistance(Pt.pBits,Pt.ppl,Pt.hei,tabA,numa,1000);
		}
		else {
			numb=BorderErosion(tabB,tabA,numa,8);
			OuterDistance(Pt.pBits,Pt.ppl,Pt.hei,tabB,numb,1000);
  			DrawBox(Pt.pBits,Pt.ppl,Pt.hei,1,0);
		}
	}

	free(tabA);  
	free(tabB);  
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pTempDibs);
}
  
void CVCIPHView::FeatherArea0()             //  Feather Area
{
	struct IMAGE_PARAMENTS Pw;
 	HDC    hDCm,hDCt;
	int    n;
     
	n=20;
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);

	GetImageParaments(&Pw,pWorkDibs);
 	DeleteDibs(pTempDibs);
	pTempDibs=CreateDibs(Pw.wid,Pw.hei,8);
	pTempDibs->SetGrayPalette();
   	hDCm = GetMemDC(pMaskDibs->hBitmap);
	hDCt = GetMemDC(pTempDibs->hBitmap);
	BitBlt(hDCt,0,0,Pw.wid,Pw.hei,hDCm,0,0,SRCCOPY);
	ReleaseMemDC(hDCm);
   	ReleaseMemDC(hDCt);

	if (LINEDISTANCE==0) {
 		FeatherArea(pTempDibs,n,0);
	}
	else if (LINEDISTANCE==1) {
		FeatherAreaL(pTempDibs,n,0);
	}
	else if (LINEDISTANCE==2) {
		FeatherAreaE(pTempDibs,n,0);
	}
 
  	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pTempDibs);
}

void CVCIPHView::FeatherBlendA0() 
{
	struct IMAGE_PARAMENTS Pw;
 	HDC    hDCm,hDCt;
	int    n;
 
	n=20;
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);

	GetImageParaments(&Pw,pWorkDibs);
 	DeleteDibs(pTempDibs);
	pTempDibs=CreateDibs(Pw.wid,Pw.hei,8);
	pTempDibs->SetGrayPalette();
   	hDCm = GetMemDC(pMaskDibs->hBitmap);
	hDCt = GetMemDC(pTempDibs->hBitmap);
	BitBlt(hDCt,0,0,Pw.wid,Pw.hei,hDCm,0,0,SRCCOPY);
	ReleaseMemDC(hDCm);
   	ReleaseMemDC(hDCt);

	if (LINEDISTANCE==0) {
		FeatherArea(pTempDibs,n,1);
	}
	else if (LINEDISTANCE==1) {
		FeatherAreaL(pTempDibs,n,1);
	}
	else {
		FeatherAreaE(pTempDibs,n,1);
	}
  
 	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pTempDibs);
}

void CVCIPHView::FeatherBlendB0() 
{
	struct IMAGE_PARAMENTS Pw,Pa,Pt,P2;
 	HDC    hDCm,hDCt,hDCa;
	BYTE   *bufw,*bufa,*buf;
	int    i,Alpha,n;
 
	n=20;
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);

	GetImageParaments(&Pw,pWorkDibs);
	GetImageParaments(&Pa,pAddDibs);
 	if ((Pw.wid!=Pa.wid)||(Pw.hei!=Pa.hei)) {
 		MessageBox("图像尺寸不一致!","警告",MB_OK);
 		return;
	}
	
 	DeleteDibs(pTempDibs);
	pTempDibs=CreateDibs(Pw.wid,Pw.hei,8);
	pTempDibs->SetGrayPalette();
	GetImageParaments(&Pt,pTempDibs);
   	hDCm = GetMemDC(pMaskDibs->hBitmap);
	hDCt = GetMemDC(pTempDibs->hBitmap);
	BitBlt(hDCt,0,0,Pw.wid,Pw.hei,hDCm,0,0,SRCCOPY);
	ReleaseMemDC(hDCm);
   	ReleaseMemDC(hDCt);

	if (LINEDISTANCE==0) {
		FeatherArea(pTempDibs,n,1);
	}
	else if (LINEDISTANCE==1) {
		FeatherAreaL(pTempDibs,n,1);
	}
	else {
		FeatherAreaE(pTempDibs,n,1);
	}
//---------------------------------------------------------
	DeleteDibs(pTmp2Dibs);
	pTmp2Dibs=CreateDibs(Pw.wid,Pw.hei,24);
	GetImageParaments(&P2,pTmp2Dibs);
	if (Pw.bits==24) {
 		hDCm = GetMemDC(pTempDibs->hBitmap);
		hDCt = GetMemDC(pTmp2Dibs->hBitmap);
		BitBlt(hDCt,0,0,Pw.wid,Pw.hei,hDCm,0,0,SRCCOPY);
		ReleaseMemDC(hDCm);
   		ReleaseMemDC(hDCt);
	}
	else {
		memcpy(P2.pBits,Pt.pBits,P2.size);
	}
	buf =P2.pBits;
 	bufw=Pw.pBits;	 bufa=Pa.pBits;
	if (Pw.bits!=Pa.bits) {
		DeleteDibs(pTempDibs);
		pTempDibs=CreateDibs(Pw.wid,Pw.hei,Pw.bits);
		if (Pw.bits==8)
			pTempDibs->SetGrayPalette();
		GetImageParaments(&Pt,pTempDibs);
 		hDCa = GetMemDC(pAddDibs->hBitmap);
 		hDCt = GetMemDC(pTempDibs->hBitmap);
  		BitBlt(hDCt,0,0,Pw.ppl,Pw.hei,hDCa,0,0,SRCCOPY);
    	ReleaseMemDC(hDCa);
   		ReleaseMemDC(hDCt);
		bufa=Pt.pBits;
	}
 	Alpha=0;
  	for (i=0;i<Pw.size;i++) {
		Alpha=(*buf++);
		(*bufw)=((Alpha*(*bufa)+(255-Alpha)*(*bufw))>>8)&0xff;
		bufw++;		bufa++;
	}
}
  
//
//---------------------------------------------------------

void CVCIPHView::OnCircleMask()             //  建立选区
{
	struct IMAGE_PARAMENTS Pw,Pm;
	HDC    hDCw,hDCm;
	HBRUSH hBrush;
	HPEN   hPen;
	int    x,y,k;
 
	GetImageParaments(&Pw,pWorkDibs);
 	hDCw= GetMemDC(Pw.hBitmap);

	hPen=(HPEN)   GetStockObject((int) WHITE_PEN);
	hBrush=(HBRUSH) GetStockObject((int) WHITE_BRUSH); 
	SelectObject(hDCw,hPen);
	SelectObject(hDCw,hBrush);
	k=min(Pw.wid,Pw.hei)/3;
	x=Pw.wid/2;		y=Pw.hei/2;
	PatBlt(hDCw,0,0,Pw.ppl,Pw.hei,BLACKNESS);
	if (AREAFORM==0) {
		Ellipse(hDCw,x-k,y-k,x+k,y+k);
	}
	else {
		Ellipse(hDCw,x-k,y-k+50,x+k,y+k+50);
		Ellipse(hDCw,30,30+50,100,100+50);
		Ellipse(hDCw,340,50,500,160+50);

		hPen=(HPEN)   GetStockObject((int) BLACK_PEN);
		hBrush=(HBRUSH) GetStockObject((int) BLACK_BRUSH); 
		SelectObject(hDCw,hPen);
		SelectObject(hDCw,hBrush);
		Ellipse(hDCw,128+20,128+128+50,384+20,384+128+50);

		hPen=(HPEN)   GetStockObject((int) WHITE_PEN);
		hBrush=(HBRUSH) GetStockObject((int) WHITE_BRUSH); 
		SelectObject(hDCw,hPen);
		SelectObject(hDCw,hBrush);
		Ellipse(hDCw,30+190,30+50+280,150+190,150+50+280);
	}
	
	pMaskDibs=CreateDibs(Pw.ppl,Pw.hei,1);
	pMaskDibs->setpalette(0,0,0,0);
	pMaskDibs->setpalette(1,255,255,255);
	GetImageParaments(&Pm,pMaskDibs);
 	hDCm= GetMemDC(Pm.hBitmap);

	BitBlt(hDCm,0,0,Pm.ppl,Pm.hei,hDCw,0,0,SRCCOPY);
   	ReleaseMemDC(hDCw); 
   	ReleaseMemDC(hDCm); 
	Invalidate();
}

void CVCIPHView::OnCreateMask()             //  建立垂直渐变蒙板
{
	struct IMAGE_PARAMENTS Pw,Pm;
	int    i,j,k;
	BYTE   *buf;

	GetImageParaments(&Pw,pWorkDibs);
 	DeleteDibs(pMaskDibs);
	pMaskDibs=CreateDibs(Pw.wid,Pw.hei,8);
	pMaskDibs->SetGrayPalette();

	GetImageParaments(&Pm,pMaskDibs);
 	buf=Pm.pBits;
	for (i=0;i<Pm.hei;i++) {
		k=255*i/(Pm.hei-1);
		for (j=0;j<Pm.bpl;j++) (*buf++)=k;
	}

	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pMaskDibs);
	Invalidate();
}

void CVCIPHView::OnCreateMaska()            //  建立水平渐变蒙板
{
	struct IMAGE_PARAMENTS Pw,Pm;
	int    i,j;
	BYTE   *buf;
	double dd,d1;
 
	GetImageParaments(&Pw,pWorkDibs);
 	DeleteDibs(pMaskDibs);
	pMaskDibs=CreateDibs(Pw.wid,Pw.hei,8);
	pMaskDibs->SetGrayPalette();

	GetImageParaments(&Pm,pMaskDibs);
 	buf=Pm.pBits;
	d1=255.0/(Pm.wid-1);
 	for (i=0;i<Pm.hei;i++) {
		for (j=0,dd=0;j<Pm.bpl;j++,dd+=d1) {
			(*buf++)=(BYTE) dd;
		}
	}

	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pMaskDibs);
	Invalidate();
}

void CVCIPHView::OnCreateMaskb()            //  建立径向渐变蒙板
{
	struct IMAGE_PARAMENTS Pw,Pm;
	HDC    hDCm;
	HBRUSH hBrush;
	HPEN   hPen;
	int    x,y,k,pg[256],table[256];
 
	GetImageParaments(&Pw,pWorkDibs);
	pMaskDibs=CreateDibs(Pw.ppl,Pw.hei,8);
	pMaskDibs->SetGrayPalette();
 	GetImageParaments(&Pm,pMaskDibs);
  	hDCm= GetMemDC(Pm.hBitmap);
	hPen=(HPEN)   GetStockObject((int) WHITE_PEN);
	hBrush=(HBRUSH) GetStockObject((int) WHITE_BRUSH); 
	SelectObject(hDCm,hPen);
	SelectObject(hDCm,hBrush);
	k=min(Pm.wid,Pm.hei)/2;
	x=Pm.wid/2;		y=Pm.hei/2;
	PatBlt(hDCm,0,0,Pm.ppl,Pm.hei,BLACKNESS);
	Ellipse(hDCm,x-k,y-k,x+k,y+k);
   	ReleaseMemDC(hDCm); 

	Distance5(Pm.pBits,Pm.ppl,Pm.hei);
	Histog(Pm.pBits,pg,Pm.ppl,Pm.hei);
	GT_linear(pg,table);
   	GrayTransform(Pm.pBits,Pm.ppl,Pm.hei,table);
 
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pMaskDibs);
	Invalidate();
}

//---------------------------------------------------------

void CVCIPHView::FeatherArea(CDibs* pDibs,int n,int flag)
{
	struct IMAGE_PARAMENTS P;
   	HDC    hDC,hDCs;
	int    i,table[256];
     
 	GetImageParaments(&P,pDibs);
	DeleteDibs(pTmp2Dibs);
	pTmp2Dibs=CreateDibs(P.wid,P.hei,8);
	pTmp2Dibs->SetGrayPalette();
	memcpy(pTmp2Dibs->pBits,P.pBits,P.size);

   	hDC = GetMemDC(pDibs->hBitmap);
   	hDCs= GetMemDC(pTmp2Dibs->hBitmap);

	PatBlt(hDC,0,0,P.ppl,P.hei,DSTINVERT);
	Distance5(P.pBits,P.ppl,P.hei);
 	table[0]=0;
	if (flag==0) {
		for (i=1;i<n;i++)   table[i]=255;
		for (i=n;i<256;i++) table[i]=0;
	}
	else {
		for (i=1;i<n;i++)   table[i]=128-255*i/2/n;
		for (i=n;i<256;i++) table[i]=0;
	}
   	GrayTransform(P.pBits,P.ppl,P.hei,table);

	Distance5(pTmp2Dibs->pBits,P.ppl,P.hei);
	if (flag==1) {
 		for (i=1;i<n;i++)   table[i]=128+255*i/2/n;
		for (i=n;i<256;i++) table[i]=255;
	}
   	GrayTransform(pTmp2Dibs->pBits,P.ppl,P.hei,table);
 	BitBlt(hDC,0,0,P.ppl,P.hei,hDCs,0,0,SRCPAINT);

   	ReleaseMemDC(hDC);
   	ReleaseMemDC(hDCs);
}

int  InnerDistance(BYTE *buf,int Dx,int Dy,struct TAB *tabA,int num,int n)   
{                                           //  距离变换
  int  i,k,num1,num2,num3;
  struct TAB *tabB,*tabC,*tab1,*tab2;
  BYTE **list;

  list =(BYTE**)malloc(Dy*sizeof(BYTE*));
  for (i=0;i<Dy;i++) list[i] =buf+i*Dx;

  tabB=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);
  tabC=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);

  num1=BorderDilation(tabB,tabA,num,8);
  num =RegionCopy(tabA,tabB,num1);
  num3=RegionCopy(tabC,tabA,num);
  for (i=0;i<num;i++) tabA[i].label=i+1;
  CreateLineRelateI(tabC,num3);

  num2=num;
  i=0;
  do {
    num1=num2;
	if (i%2==0) {
	  tab1=tabA;	  tab2=tabB;
	}
	else {
	  tab1=tabB;	  tab2=tabA;
	}
	if (LINEDISTANCE==1) {
	  if ((i%5)%2) k=4;
	  else k=8;
      num2=BorderErosion(tab2,tab1,num1,k);
      CopyLineTableData(list,tab2,num2,0,0,i+1);
	}
	else {
      num2=BorderErosion(tab2,tab1,num1,8);
      DistanceCorrectI(tab2,num2,tabC,num3,i+1);
      if (type==0)
        CopyLineTableData(list,tab2,num2,0,0,i+1);
	  else
        CopyLineTableData(list,tab2,num2,0,0,-1);
	}
  	i++;
  }
  while((num2)&&(i<n));
  
  free(tabB);  
  free(tabC);  
  free(list);
  return(i);
}

int  OuterDistance(BYTE *buf,int Dx,int Dy,struct TAB *tabA,int num,int n)   
{                                           //  距离变换
  int  i,k,num0,num1,num2;
  struct TAB *tabB,*tab0,*tab1,*tab2;
  BYTE **list;
  
  list =(BYTE**)malloc(Dy*sizeof(BYTE*));
  for (i=0;i<Dy;i++) list[i] =buf+i*Dx;
 
  tabB=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);
  if (LINEDISTANCE==2) {
    tab0=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);
 	num0=RegionCopy(tab0,tabA,num);
	for (i=0;i<num;i++) tabA[i].label=i+1;
    CreateLineRelateO(tab0,num0);
  }
  num2=num;
  i=0;
  do {
    num1=num2;
	if (i%2==0) {
	  tab1=tabA;	  tab2=tabB;
	}
	else {
	  tab1=tabB;	  tab2=tabA;
	}
	if ((i%5)%2) k=8;
	else k=4;
    num2=BorderDilationCut(tab2,tab1,Dx,Dy,num1,k);

   	if ((LINEDISTANCE==2)&&(k==4))
      DistanceCorrectO(tab2,num2,tab0,num0,i+1);
    if (type==0)
      CopyLineTableData(list,tab2,num2,0,0,i+1);
	else
      CopyLineTableData(list,tab2,num2,0,0,-1);
   	i++;
	if ((tab2[0].x2==0)&&(tab2[1].x1==Dx-1)&&
	  (tab2[num2-2].x2==0)&&(tab2[num2-1].x1==Dx-1)) break;
  }
  while((num2)&&(i<n));
  
  free(list);
  free(tabB);  
  if (LINEDISTANCE==2)
    free(tab0);  
  return(i);
}

void FeatherAreaL(CDibs* pDibs,int n,int flag)
{
	struct IMAGE_PARAMENTS P;
	struct TAB *tabA,*tabB,*tabC,*tabD,*tab1,*tab2;   
	int    i,k,num,numt,numd,nume,Dx,Dy,table[256];
	BYTE   *buf,**list;
 
	GetImageParaments(&P,pDibs);
	Dx=P.ppl;		Dy=P.hei;
	buf=pDibs->pBits;
	list =(BYTE**)malloc(P.hei*sizeof(BYTE*));
	for (i=0;i<P.hei;i++) list[i] =P.pBits+i*P.ppl;
	tabA=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);
	tabB=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);
	tabC=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);
	tabD=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);

	num=CreateTab(buf,Dx,Dy,tabA);
	memcpy(tabD,tabA,num*sizeof(struct TAB));
	numt=num;
	if (flag==0) {
		for (i=0;i<n;i++) {
			if (i%2==0) {
				tab1=tabA;
				tab2=tabB;
			}
			else {
				tab1=tabB;
				tab2=tabA;
			}
			if ((i%5)%2) k=8;
			else k=4;
 			numd=LineDilationCut(tab2,tab1,P.ppl,P.hei,num,k);
			num=numd;
		}
 		memcpy(tabC,tab2,numd*sizeof(struct TAB));

		num=numt;
		memcpy(tabA,tabD,num*sizeof(struct TAB));
		for (i=0;i<n;i++) {
			if (i%2==0) {
				tab1=tabA;
				tab2=tabB;
			}
			else {
				tab1=tabB;
				tab2=tabA;
			}
			if ((i%5)%2) k=8;
			else k=4;
 			nume=LineErosion(tab2,tab1,num,k);
			num=nume;
		}
 		num=RegionSUB(tabC,numd,tab2,nume);
		memset(buf,0,Dx*Dy);
		CopyLineTableData(list,tabC,num,0,0,255);
 	}
	else {
		for (i=0;i<2*n;i++) table[i]=255*i/(2*n);
		for (i=0;i<n;i++) {
			if (i%2==0) {
				tab1=tabA;
				tab2=tabB;
			}
			else {
				tab1=tabB;
				tab2=tabA;
			}
			if ((i%5)%2) k=8;
			else k=4;
			numd=BorderDilationCut(tab2,tab1,P.ppl,P.hei,num,k);
			CopyLineTableData(list,tab2,numd,0,0,table[n-1-i]);
 			num=numd;
		}
		num=numt;
		memcpy(tabA,tabD,num*sizeof(struct TAB));
 		for (i=0;i<n;i++) {
			if (i%2==0) {
				tab1=tabA;
				tab2=tabB;
			}
			else {
				tab1=tabB;
				tab2=tabA;
			}
			if ((i%5)%2) k=8;
			else k=4;
			CopyLineTableData(list,tab1,num,0,0,table[n+i]);
 			nume=LineErosion(tab2,tab1,num,k);
			num=nume;
		}
    }

	free(list);
 	free(tabA);  
	free(tabB);  
	free(tabC);  
	free(tabD);  
}

void FeatherAreaE(CDibs* pDibs,int n,int flag)
{
	struct IMAGE_PARAMENTS P;
	struct TAB *tabA,*tabB,*tabC,*tabD,*tab0,*tab1,*tab2;   
	int    i,k,num,num0,num1,numt,numd,nume,Dx,Dy,table[256];
	BYTE   *buf,**list;
 
	GetImageParaments(&P,pDibs);
	Dx=P.ppl;		Dy=P.hei;
	buf=pDibs->pBits;
    tab0=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);
	tabA=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);
	tabB=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);
	tabC=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);
	tabD=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);
	list =(BYTE**)malloc(P.hei*sizeof(BYTE*));
	for (i=0;i<P.hei;i++) list[i] =P.pBits+i*P.ppl;

	num=CreateTab(buf,Dx,Dy,tabA);
 	numt=num;
	memcpy(tabD,tabA,num*sizeof(struct TAB));
 	num1=RegionCopy(tabB,tabA,num);
	num=BorderErosion(tabA,tabB,num1,8);
 	num0=RegionCopy(tab0,tabA,num);
	for (i=0;i<num;i++) tabA[i].label=i+1;
	CreateLineRelateO(tab0,num0);
	if (flag==0) {
		for (i=0;i<n;i++) {
			if (i%2==0) {
				tab1=tabA;
				tab2=tabB;
			}
			else {
				tab1=tabB;
				tab2=tabA;
			}
			if ((i%5)%2) k=8;
			else k=4;
  			numd=BorderDilationCut(tab2,tab1,P.ppl,P.hei,num,k);
   			DistanceCorrectO(tab2,numd,tab0,num0,i+1);
 			num=numd;
		}
  		memcpy(tabC,tab2,num*sizeof(struct TAB));
		numd=FillAreaHole(tabC,num);

		num=numt;
		memcpy(tabA,tabD,num*sizeof(struct TAB));
        num1=BorderDilation(tabB,tabA,num,8);
        num =RegionCopy(tabA,tabB,num1);
		num0=RegionCopy(tab0,tabA,num);
		for (i=0;i<num;i++) tabA[i].label=i+1;
		CreateLineRelateI(tab0,num0);
 		for (i=0;i<n;i++) {
			if (i%2==0) {
				tab1=tabA;
				tab2=tabB;
			}
			else {
				tab1=tabB;
				tab2=tabA;
			}
			nume=BorderErosion(tab2,tab1,num,8);
   			DistanceCorrectI(tab2,nume,tab0,num0,i+1);
			num=nume;
		}
		nume=FillAreaHole(tab2,nume);
 		num=RegionSUB(tabC,numd,tab2,nume);
		memset(buf,0,Dx*Dy);
		CopyLineTableData(list,tabC,num,0,0,255);
	}
	else {
		for (i=0;i<2*n;i++) table[i]=255*i/(2*n);
		for (i=0;i<n;i++) {
			if (i%2==0) {
				tab1=tabA;
				tab2=tabB;
			}
			else {
				tab1=tabB;
				tab2=tabA;
			}
 			if ((i%5)%2) k=8;
			else k=4;
 			numd=BorderDilationCut(tab2,tab1,P.ppl,P.hei,num,k);
 			DistanceCorrectO(tab2,numd,tab0,num0,i+1);
			CopyLineTableData(list,tab2,numd,0,0,table[n-1-i]);
 			num=numd;
		}
		num=numt;
 		memcpy(tabA,tabD,num*sizeof(struct TAB));
        num1=BorderDilation(tabB,tabA,num,8);
        num =RegionCopy(tabA,tabB,num1);
 		num0=RegionCopy(tab0,tabA,num);
		for (i=0;i<num;i++) tabA[i].label=i+1;
		CreateLineRelateI(tab0,num0);
 		for (i=0;i<n;i++) {
			if (i%2==0) {
				tab1=tabA;
				tab2=tabB;
			}
			else {
				tab1=tabB;
				tab2=tabA;
			}
 			nume=BorderErosion(tab2,tab1,num,8);
   			DistanceCorrectI(tab2,nume,tab0,num0,i+1);
			CopyLineTableData(list,tab1,num,0,0,table[n+i]);
 			num=nume;
		}
    }

	free(list);
 	free(tab0);  
 	free(tabA);  
	free(tabB);  
	free(tabC);  
	free(tabD);  
}

void ColorToGray(BYTE *buf0,int ppl0,BYTE *buf1,int ppl1,int Dy)
{
	BYTE *buff,*buf;
	BYTE tabR[256],tabG[256],tabB[256];
	int  i,j,k,n,ppl;
  
	for (i=0;i<256;i++) {
		tabB[i]=(int) (0.33*i);		tabG[i]=(int) (0.33*i);
		tabR[i]=(int) (0.33*i);
	}
 	ppl=min(ppl0,ppl1);
	for (j=0;j<Dy;j++) {
		buf =buf1+j*3*ppl1;
		buff=buf0+j*ppl0;
		for (i=0,k=0;i<ppl;i++,k+=3) {
 			n=tabB[*(buf++)]+tabG[*(buf++)]+tabR[*(buf++)];
			*(buff++)=n;
		}
	}
}

//---------------------------------------------------------
//   测速程序
void CVCIPHView::ModifyPalette1()          //  修改调色板
{
    struct IMAGE_PARAMENTS P;
	int    pg[256],T_gray[256];
	int    L,t,k;
	double d1,d2;
	char   ch[20];
 
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);

    GetImageParaments(&P,pWorkDibs);
 	Histog(P.pBits,pg,P.ppl,P.hei);
	GT_Equal(pg,T_gray);

	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (k=0;k<t;k++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d1=(float)L/t;

 	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (k=0;k<t;k++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);

 			pWorkDibs->SetGTPalette(T_gray);  //  修改调色板
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d2=(float)L/t-d1+0.0005;
	if (d2<=d1) d2=0.001;
	sprintf(ch,"%5.3f 毫秒",d2);
	MessageBox(ch,"运行时间",MB_OK);
}

void CVCIPHView::ModifyPixel1()            //  BitBlt 操作
{
    struct IMAGE_PARAMENTS P;
	int    pg[256],T_gray[256];
	HDC    hDCw,hDCt;
	int    L,t,k;
	double d1,d2;
	char   ch[20];
 
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);

    GetImageParaments(&P,pWorkDibs);
 	Histog(P.pBits,pg,P.ppl,P.hei);
	GT_Equal(pg,T_gray);

	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (k=0;k<t;k++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d1=(float)L/t;

 	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (k=0;k<t;k++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);

  			pWorkDibs->SetGTPalette(T_gray);
			DeleteDibs(pTempDibs);
			pTempDibs=CreateDibs(P.ppl,P.hei,8);
			pTempDibs->SetGrayPalette();
  			hDCw = GetMemDC(pWorkDibs->hBitmap);
			hDCt = GetMemDC(pTempDibs->hBitmap);
			BitBlt(hDCt,0,0,P.ppl,P.hei,hDCw,0,0,SRCCOPY);  //  修改像素
			ReleaseMemDC(hDCw);
   			ReleaseMemDC(hDCt);
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d2=(float)L/t;
	sprintf(ch,"%5.2f 毫秒",d2-d1+0.005);
	MessageBox(ch,"运行时间",MB_OK);

	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pTempDibs);
}

void CVCIPHView::LockTable1()              //  查找表法
{
    struct IMAGE_PARAMENTS P;
	int    pg[256],T_gray[256];
	int    i,L,t,k;
	double d1,d2;
	char   ch[20];
	BYTE   *buf;
 
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);

    GetImageParaments(&P,pWorkDibs);
 	Histog(P.pBits,pg,P.ppl,P.hei);
	GT_Equal(pg,T_gray);

	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (k=0;k<t;k++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d1=(float)L/t;

 	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (k=0;k<t;k++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);

			GetImageParaments(&P,pWorkDibs);
			buf=P.pBits;
 			for (i=0;i<P.size;i++,buf++) {                                 
				(*buf)=T_gray[(*buf)];      //  查表
			}
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d2=(float)L/t;
	sprintf(ch,"%5.2f 毫秒",d2-d1+0.005);
	MessageBox(ch,"运行时间",MB_OK);
}

void CVCIPHView::AlphaBlend1()             //  AlphaBlend
{
	struct IMAGE_PARAMENTS Pw,Pa;
	HDC  hSrcDC,hTrcDC;
	BLENDFUNCTION rBlendProps;
	int  L,t,k,Alpha,wid,hei;
	double d1,d2;
	char ch[20];
 
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);

	GetImageParaments(&Pw,pWorkDibs);
	GetImageParaments(&Pa,pAddDibs);
 	wid=min(Pw.wid,Pa.wid);
	hei=min(Pw.hei,Pa.hei);

	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (k=0;k<t;k++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d1=(float)L/t;

	Alpha=100;
	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (k=0;k<t;k++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);
 			GetImageParaments(&Pw,pWorkDibs);
  			rBlendProps.BlendOp = AC_SRC_OVER;
			rBlendProps.BlendFlags = 0;
			rBlendProps.SourceConstantAlpha=Alpha;
			rBlendProps.AlphaFormat = 0;     
 			hSrcDC = GetMemDC(pAddDibs->hBitmap);
			hTrcDC = GetMemDC(pWorkDibs->hBitmap);
 			AlphaBlend(hTrcDC,0,0,wid,hei,
					hSrcDC,0,0,wid,hei,rBlendProps);
   			ReleaseMemDC(hSrcDC);
   			ReleaseMemDC(hTrcDC);
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d2=(float)L/t;
	sprintf(ch,"%5.2f 毫秒",d2-d1+0.005);
	MessageBox(ch,"运行时间",MB_OK);
}

void CVCIPHView::ImageBlendA1()            //  线性叠加
{
	struct IMAGE_PARAMENTS Pw,Pa,Pt;
	HDC  hDCa,hDCt;
	BYTE *bufw,*bufa;
	int  i,L,t,k,Alpha;
	double d1,d2;
	char ch[20];
  
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);

	GetImageParaments(&Pw,pWorkDibs);
	GetImageParaments(&Pa,pAddDibs);
	if ((Pw.wid!=Pa.wid)||(Pw.hei!=Pa.hei)) {
		MessageBox("图像尺寸不一致!","警告",MB_OK);
		return;
	}
 
	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (k=0;k<t;k++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d1=(float)L/t;

	Alpha=100;
 	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (k=0;k<t;k++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);
			GetImageParaments(&Pw,pWorkDibs);
			bufw=Pw.pBits;		bufa=Pa.pBits;
 			if (Pw.bits!=Pa.bits) {
				DeleteDibs(pTempDibs);
				pTempDibs=CreateDibs(Pw.wid,Pw.hei,Pw.bits);
				if (Pw.bits==8)
					pTempDibs->SetGrayPalette();
				GetImageParaments(&Pt,pTempDibs);
 				hDCa = GetMemDC(pAddDibs->hBitmap);
  				hDCt = GetMemDC(pTempDibs->hBitmap);
  				BitBlt(hDCt,0,0,Pw.ppl,Pw.hei,hDCa,0,0,SRCCOPY);
     			ReleaseMemDC(hDCa);
   				ReleaseMemDC(hDCt);
				bufa=Pt.pBits;
			}
   			for (i=0;i<Pw.size;i++) {
  				(*bufw)=((Alpha*(*bufa)+(255-Alpha)*(*bufw))>>8)&0xff;
				                            //  计算合成强度
				bufw++;		bufa++;
			}
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d2=(float)L/t;
	sprintf(ch,"%5.2f 毫秒",d2-d1+0.005);
	MessageBox(ch,"运行时间",MB_OK);
}

void CVCIPHView::ImageBlend1()             //  查表叠加
{
	struct IMAGE_PARAMENTS Pw,Pa,Pt;
	HDC  hDCa,hDCt;
	BYTE *bufw,*bufa,TabS[256],TabD[256];
	int  i,L,t,k,Alpha;
	double d1,d2;
	char ch[20];
 
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);

	GetImageParaments(&Pw,pWorkDibs);
	GetImageParaments(&Pa,pAddDibs);
	if ((Pw.wid!=Pa.wid)||(Pw.hei!=Pa.hei)) {
		MessageBox("图像尺寸不一致!","警告",MB_OK);
		return;
	}
 
	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (k=0;k<t;k++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d1=(float)L/t;

	Alpha=100;
 	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (k=0;k<t;k++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);
			GetImageParaments(&Pw,pWorkDibs);
			bufw=Pw.pBits;		bufa=Pa.pBits;
 			if (Pw.bits!=Pa.bits) {
				DeleteDibs(pTempDibs);
				pTempDibs=CreateDibs(Pw.wid,Pw.hei,Pw.bits);
				if (Pw.bits==8)
					pTempDibs->SetGrayPalette();
				GetImageParaments(&Pt,pTempDibs);
 				hDCa = GetMemDC(pAddDibs->hBitmap);
  				hDCt = GetMemDC(pTempDibs->hBitmap);
  				BitBlt(hDCt,0,0,Pw.ppl,Pw.hei,hDCa,0,0,SRCCOPY);
     			ReleaseMemDC(hDCa);
   				ReleaseMemDC(hDCt);
				bufa=Pt.pBits;
			}
			for (i=0;i<256;i++) TabS[i]=Alpha*i/255;  //  计算前景查找表
			for (i=0;i<256;i++) TabD[i]=i-TabS[i];    //  计算背景查找表
  			for (i=0;i<Pw.size;i++) {
				(*bufw)=TabS[(*bufa)]+TabD[(*bufw)];  //  查表后叠加
				bufw++;		bufa++;                   //  指针增量
			}
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d2=(float)L/t;
	sprintf(ch,"%5.2f 毫秒",d2-d1+0.005);
	MessageBox(ch,"运行时间",MB_OK);
}

void CVCIPHView::BitBlt1()                 //  5次BitBlt
{
	struct IMAGE_PARAMENTS Pw,Pa;
	HDC  hDCm,hDCt,hDCw,hDCa;
 	int  L,i,t;
	double d1,d2;
	char ch[20];
 
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);

	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (i=0;i<t;i++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d1=(float)L/t;

	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (i=0;i<t;i++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);

			GetImageParaments(&Pw,pWorkDibs);
			GetImageParaments(&Pa,pAddDibs);

 			DeleteDibs(pTempDibs);
			pTempDibs=CreateDibs(Pw.wid,Pw.hei,Pw.bits);
			if (Pw.bits==8)
				pTempDibs->SetGrayPalette();
  			hDCm = GetMemDC(pMaskDibs->hBitmap);
			hDCt = GetMemDC(pTempDibs->hBitmap);
			hDCw = GetMemDC(pWorkDibs->hBitmap);
			hDCa = GetMemDC(pAddDibs->hBitmap);

			BitBlt(hDCt,0,0,Pw.wid,Pw.hei,hDCm,0,0,SRCCOPY);
 			BitBlt(hDCt,0,0,Pw.wid,Pw.hei,hDCw,0,0,SRCERASE);
  			BitBlt(hDCw,0,0,Pw.wid,Pw.hei,hDCa,0,0,SRCCOPY);
 			BitBlt(hDCw,0,0,Pw.wid,Pw.hei,hDCm,0,0,SRCAND);
 			BitBlt(hDCw,0,0,Pw.wid,Pw.hei,hDCt,0,0,SRCPAINT);

			ReleaseMemDC(hDCm);
   			ReleaseMemDC(hDCt);
   			ReleaseMemDC(hDCw);
   			ReleaseMemDC(hDCa);
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d2=(float)L/t;
	sprintf(ch,"%5.2f 毫秒",d2-d1+0.005);
	MessageBox(ch,"运行时间",MB_OK);
}

void CVCIPHView::MaskBlend1()              //  掩模控制合成
{
	struct IMAGE_PARAMENTS Pw,Pa,Pm,Pt,P2;
 	HDC  hDCm,hDCt,hDCa;
	BYTE *bufw,*bufa,*buf;
	int  i,L,j,t;
	double d1,d2;
	char ch[20];
 
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);

	GetImageParaments(&Pw,pWorkDibs);
	GetImageParaments(&Pa,pAddDibs);
	GetImageParaments(&Pm,pMaskDibs);
	if ((Pw.wid!=Pa.wid)||(Pw.hei!=Pa.hei)||
		(Pm.bits!=1)) {
		MessageBox("图像尺寸不一致!","警告",MB_OK);
 		return;
	}
 
	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (j=0;j<t;j++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d1=(float)L/t;

 	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (j=0;j<t;j++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);

			GetImageParaments(&Pw,pWorkDibs);
			GetImageParaments(&Pa,pAddDibs);
			GetImageParaments(&Pm,pMaskDibs);
 			if ((Pw.wid!=Pa.wid)||(Pw.hei!=Pa.hei)||
				(Pm.bits!=1)) return;
  
			DeleteDibs(pTmp2Dibs);
 			pTmp2Dibs=CreateDibs(Pw.wid,Pw.hei,Pw.bits);
			if (Pw.bits==8)
				pTmp2Dibs->SetGrayPalette();
			GetImageParaments(&P2,pTmp2Dibs);
 			hDCm = GetMemDC(pMaskDibs->hBitmap);
			hDCt = GetMemDC(pTmp2Dibs->hBitmap);
			BitBlt(hDCt,0,0,Pw.ppl,Pw.hei,hDCm,0,0,SRCCOPY);
			ReleaseMemDC(hDCm);
   			ReleaseMemDC(hDCt);
 
			buf =P2.pBits;
 			bufw=Pw.pBits;		bufa=Pa.pBits;
 			if (Pw.bits!=Pa.bits) {
				DeleteDibs(pTempDibs);
				pTempDibs=CreateDibs(Pw.wid,Pw.hei,Pw.bits);
				if (Pw.bits==8)
					pTempDibs->SetGrayPalette();
				GetImageParaments(&Pt,pTempDibs);
				hDCa = GetMemDC(pAddDibs->hBitmap);
 				hDCt = GetMemDC(pTempDibs->hBitmap);
				BitBlt(hDCt,0,0,Pw.ppl,Pw.hei,hDCa,0,0,SRCCOPY);
/*
				if (Pw.bits==24)
  					BitBlt(hDCt,0,0,Pw.ppl,Pw.hei,hDCa,0,0,SRCCOPY);
				else
					ColorToGray(Pt.pBits,Pt.ppl,Pa.pBits,Pa.ppl,Pa.hei);
*/
    			ReleaseMemDC(hDCa);
   				ReleaseMemDC(hDCt);
				bufa=Pt.pBits;
			}
   			for (i=0;i<Pw.size;i++) {
 				if (*buf++) (*bufw)=(*bufa);  //  非零则传递
 				bufw++;		bufa++;
			}
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d2=(float)L/t;
	sprintf(ch,"%5.2f 毫秒",d2-d1+0.005);
	MessageBox(ch,"运行时间",MB_OK);
}

void CVCIPHView::ImageBitBlt1()            //  线性叠加
{
	struct IMAGE_PARAMENTS Pw,Pa,Pm,Pt,P2;
 	HDC  hDCm,hDCt,hDCa;
	BYTE *bufw,*bufa,*buf;
	int  i,L,t,k,Alpha;
	double d1,d2;
	char ch[20];
 	
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);

	GetImageParaments(&Pw,pWorkDibs);
	GetImageParaments(&Pa,pAddDibs);
	GetImageParaments(&Pm,pMaskDibs);
	if ((Pw.wid!=Pa.wid)||(Pw.hei!=Pa.hei)||
		(Pm.bits!=8)) {
		MessageBox("图像尺寸不一致!","警告",MB_OK);
 		return;
	}
 
	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (k=0;k<t;k++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d1=(float)L/t;

 	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (k=0;k<t;k++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);

			GetImageParaments(&Pw,pWorkDibs);
			GetImageParaments(&Pa,pAddDibs);
			GetImageParaments(&Pm,pMaskDibs);
 			if (Pw.bits==24) {
				DeleteDibs(pTmp2Dibs);
 				pTmp2Dibs=CreateDibs(Pw.wid,Pw.hei,24);
				GetImageParaments(&P2,pTmp2Dibs);
 				hDCm = GetMemDC(pMaskDibs->hBitmap);
				hDCt = GetMemDC(pTmp2Dibs->hBitmap);
				BitBlt(hDCt,0,0,Pw.wid,Pw.hei,hDCm,0,0,SRCCOPY);
				ReleaseMemDC(hDCm);
   				ReleaseMemDC(hDCt);
				buf =P2.pBits;
			}
			else buf=Pm.pBits;

 			bufw=Pw.pBits;	 bufa=Pa.pBits;
			if (Pw.bits!=Pa.bits) {
				DeleteDibs(pTempDibs);
				pTempDibs=CreateDibs(Pw.wid,Pw.hei,Pw.bits);
				if (Pw.bits==8)
					pTempDibs->SetGrayPalette();
				GetImageParaments(&Pt,pTempDibs);
 				hDCa = GetMemDC(pAddDibs->hBitmap);
 				hDCt = GetMemDC(pTempDibs->hBitmap);
				BitBlt(hDCt,0,0,Pw.ppl,Pw.hei,hDCa,0,0,SRCCOPY);
     			ReleaseMemDC(hDCa);
   				ReleaseMemDC(hDCt);
				bufa=Pt.pBits;
			}
 			Alpha=0;
  			for (i=0;i<Pw.size;i++) {
				Alpha=(*buf++);
  				(*bufw)=((Alpha*(*bufa)+(255-Alpha)*(*bufw))>>8)&0xff;
				                            //  计算合成强度
				bufw++;		bufa++;
			}
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d2=(float)L/t;
	sprintf(ch,"%5.2f 毫秒",d2-d1+0.005);
	MessageBox(ch,"运行时间",MB_OK);
}

void CVCIPHView::DistanceB(int flag) 
{
	struct IMAGE_PARAMENTS Pw,Pt;
	struct TAB *tabA,*tabB;   
  	HDC    hDCm,hDCt;
	int    L,t,k;
	double d1,d2;
  	char   ch[20];
 	int    numa,numb;
 	
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);
 
	tabA=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);
	tabB=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);

	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (k=0;k<t;k++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d1=(float)L/t;

 	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (k=0;k<t;k++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);

  			GetImageParaments(&Pw,pWorkDibs);
 			DeleteDibs(pTempDibs);
			pTempDibs=CreateDibs(Pw.wid,Pw.hei,8);
			pTempDibs->SetGrayPalette();
   			hDCm = GetMemDC(pMaskDibs->hBitmap);
			hDCt = GetMemDC(pTempDibs->hBitmap);
			BitBlt(hDCt,0,0,Pw.wid,Pw.hei,hDCm,0,0,SRCCOPY);
			if ((LINEDISTANCE==0)&&(flag==1)) {
				PatBlt(hDCt,0,0,Pw.wid,Pw.hei,DSTINVERT);
			}
  			ReleaseMemDC(hDCm);
   			ReleaseMemDC(hDCt);

			pTempDibs->SetDefaultPalette();
  			GetImageParaments(&Pt,pTempDibs);
			if (LINEDISTANCE) {
 				numa=CreateTab(Pt.pBits,Pt.ppl,Pt.hei,tabA);
				if (flag==0)
					InnerDistance(Pt.pBits,Pt.ppl,Pt.hei,tabA,numa,1000);
				else {
					if (LINEDISTANCE==1) {
						OuterDistance(Pt.pBits,Pt.ppl,Pt.hei,tabA,numa,1000);
					}
					else {
						numb=BorderErosion(tabB,tabA,numa,8);
						OuterDistance(Pt.pBits,Pt.ppl,Pt.hei,tabB,numb,1000);
					}
					DrawBox(Pt.pBits,Pt.ppl,Pt.hei,1,0);
				}
			}
			else {
				Distance5(Pt.pBits,Pt.ppl,Pt.hei);
			}
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d2=(float)L/t;
	sprintf(ch,"%5.2f 毫秒",d2-d1+0.005);
	MessageBox(ch,"运行时间",MB_OK);

 	free(tabA);  
 	free(tabB);  
 	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pTempDibs);
}

void CVCIPHView::FeatherArea1()            //  Feather Area
{
	struct IMAGE_PARAMENTS Pw;
  	HDC    hDCm,hDCt;
	int    n,L,t,k;
	double d1,d2;
  	char   ch[20];
     
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);
 
	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (k=0;k<t;k++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d1=(float)L/t;

 	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (k=0;k<t;k++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);
    
			n=20;
 			GetImageParaments(&Pw,pWorkDibs);
 			DeleteDibs(pTempDibs);
			pTempDibs=CreateDibs(Pw.wid,Pw.hei,8);
			pTempDibs->SetGrayPalette();
   			hDCm = GetMemDC(pMaskDibs->hBitmap);
			hDCt = GetMemDC(pTempDibs->hBitmap);
			BitBlt(hDCt,0,0,Pw.wid,Pw.hei,hDCm,0,0,SRCCOPY);
			ReleaseMemDC(hDCm);
   			ReleaseMemDC(hDCt);

			if (LINEDISTANCE==0) {
				FeatherArea(pTempDibs,n,0);
			}
			else if (LINEDISTANCE==1) {
				FeatherAreaL(pTempDibs,n,0);
			}
			else {
				FeatherAreaE(pTempDibs,n,0);
			}
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d2=(float)L/t;
	sprintf(ch,"%5.2f 毫秒",d2-d1+0.005);
	MessageBox(ch,"运行时间",MB_OK);

 	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pTempDibs);
   	Invalidate();
}

void CVCIPHView::FeatherBlendA1() 
{
	struct IMAGE_PARAMENTS Pw;
  	HDC    hDCm,hDCt;
	int    n,L,t,k;
	double d1,d2;
  	char   ch[20];
 
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);
 
	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (k=0;k<t;k++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d1=(float)L/t;

 	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (k=0;k<t;k++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);
    
			n=20;
 			GetImageParaments(&Pw,pWorkDibs);
 			DeleteDibs(pTempDibs);
			pTempDibs=CreateDibs(Pw.wid,Pw.hei,8);
			pTempDibs->SetGrayPalette();
   			hDCm = GetMemDC(pMaskDibs->hBitmap);
			hDCt = GetMemDC(pTempDibs->hBitmap);
			BitBlt(hDCt,0,0,Pw.wid,Pw.hei,hDCm,0,0,SRCCOPY);
			ReleaseMemDC(hDCm);
   			ReleaseMemDC(hDCt);

			if (LINEDISTANCE==0) {
				FeatherArea(pTempDibs,n,1);
			}
			else if (LINEDISTANCE==1) {
				FeatherAreaL(pTempDibs,n,1);
			}
			else {
				FeatherAreaE(pTempDibs,n,1);
			}
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d2=(float)L/t;
	sprintf(ch,"%5.2f 毫秒",d2-d1+0.005);
	MessageBox(ch,"运行时间",MB_OK);

 	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pTempDibs);
   	Invalidate();
}

void CVCIPHView::FeatherBlendB1() 
{
	struct IMAGE_PARAMENTS Pw,Pa,Pt,Pm,P2;
 	HDC    hDCm,hDCt,hDCa;
	BYTE   *bufw,*bufa,*buf;
	int    i,Alpha,n;
	int    L,t,k;
	double d1,d2;
	char   ch[20];
  
	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pSaveDibs);

	GetImageParaments(&Pw,pWorkDibs);
	GetImageParaments(&Pa,pAddDibs);
	GetImageParaments(&Pm,pMaskDibs);
	if ((Pw.wid!=Pa.wid)||(Pw.hei!=Pa.hei)||
		(Pm.bits!=1)) {
  		MessageBox("图像尺寸不一致!","警告",MB_OK);
 		return;
	}
 
	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (k=0;k<t;k++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d1=(float)L/t;

 	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (k=0;k<t;k++) {
			DeleteDibs(pWorkDibs);
			pWorkDibs=CopyDibs(pSaveDibs);
    
			n=20;
 			GetImageParaments(&Pw,pWorkDibs);
 			DeleteDibs(pTempDibs);
			pTempDibs=CreateDibs(Pw.wid,Pw.hei,8);
			pTempDibs->SetGrayPalette();
   			hDCm = GetMemDC(pMaskDibs->hBitmap);
			hDCt = GetMemDC(pTempDibs->hBitmap);
			BitBlt(hDCt,0,0,Pw.wid,Pw.hei,hDCm,0,0,SRCCOPY);
			ReleaseMemDC(hDCm);
   			ReleaseMemDC(hDCt);

			if (LINEDISTANCE==0) {
				FeatherArea(pTempDibs,n,1);
			}
			else if (LINEDISTANCE==1) {
				FeatherAreaL(pTempDibs,n,1);
			}
			else {
				FeatherAreaE(pTempDibs,n,1);
			}
//---------------------------------------------------------

			DeleteDibs(pTmp2Dibs);
			pTmp2Dibs=CreateDibs(Pw.wid,Pw.hei,24);
			GetImageParaments(&P2,pTmp2Dibs);
			if (Pw.bits==24) {
 				hDCm = GetMemDC(pTempDibs->hBitmap);
				hDCt = GetMemDC(pTmp2Dibs->hBitmap);
				BitBlt(hDCt,0,0,Pw.wid,Pw.hei,hDCm,0,0,SRCCOPY);
				ReleaseMemDC(hDCm);
   				ReleaseMemDC(hDCt);
			}
			else {
				memcpy(P2.pBits,Pt.pBits,P2.size);
			}
			buf =P2.pBits;
 			bufw=Pw.pBits;	 bufa=Pa.pBits;
			if (Pw.bits!=Pa.bits) {
				DeleteDibs(pTempDibs);
				pTempDibs=CreateDibs(Pw.wid,Pw.hei,Pw.bits);
				if (Pw.bits==8)
					pTempDibs->SetGrayPalette();
				GetImageParaments(&Pt,pTempDibs);
 				hDCa = GetMemDC(pAddDibs->hBitmap);
 				hDCt = GetMemDC(pTempDibs->hBitmap);
  				BitBlt(hDCt,0,0,Pw.ppl,Pw.hei,hDCa,0,0,SRCCOPY);
    			ReleaseMemDC(hDCa);
   				ReleaseMemDC(hDCt);
				bufa=Pt.pBits;
			}
 			Alpha=0;
  			for (i=0;i<Pw.size-1;i++,buf++) {
				Alpha=(*buf);
  				(*bufw)=((Alpha*(*bufa)+(255-Alpha)*(*bufw))>>8)&0xff;
 				bufw++;		bufa++;
			}
//---------------------------------------------------------
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d2=(float)L/t;
	sprintf(ch,"%5.2f 毫秒",d2-d1+0.005);
	MessageBox(ch,"运行时间",MB_OK);
}

//---------------------------------------------------------

void CVCIPHView::OnModifyPalette()          //  修改调色板
{
	if (MEASURE==0)
		ModifyPalette0();
	else
		ModifyPalette1();
	Invalidate();
}

void CVCIPHView::OnModifyPixel()            //  BitBlt 操作
{
	if (MEASURE==0)
		ModifyPixel0();
	else
		ModifyPixel1();
	Invalidate();
}

void CVCIPHView::OnLockTable()              //  查找表法
{
	if (MEASURE==0)
		LockTable0();
	else
		LockTable1();
	Invalidate();
}

void CVCIPHView::OnAlphaBlend()             //  AlphaBlend
{
	if (MEASURE==0)
		AlphaBlend0();
	else
		AlphaBlend1();
	Invalidate();
}

void CVCIPHView::OnImageBlendA()            //  线性叠加
{
	if (MEASURE==0)
		ImageBlendA0();
	else
		ImageBlendA1();
	Invalidate();
}

void CVCIPHView::OnImageBlend()             //  查表叠加
{
	if (MEASURE==0)
		ImageBlend0();
	else
		ImageBlend1();
	Invalidate();
}

void CVCIPHView::OnBitBlt()                 //  5次BitBlt
{
	if (MEASURE==0)
		BitBlt0();
	else
		BitBlt1();
	Invalidate();
}

void CVCIPHView::OnMaskBlend()              //  掩模控制合成
{
	if (MEASURE==0)
		MaskBlend0();
	else
		MaskBlend1();
	Invalidate();
}

void CVCIPHView::OnImageBitBlt()            //  线性叠加
{
	if (MEASURE==0)
		ImageBitBlt0();
	else
		ImageBitBlt1();
	Invalidate();
}

void CVCIPHView::OnDistance() 
{
	type=0;
	if (MEASURE==0)
		DistanceA(0);
	else
		DistanceB(0);
   	Invalidate();
}

void CVCIPHView::OnDistancea() 
{
	type=1;
	DistanceA(0);
   	Invalidate();
}

void CVCIPHView::OnOuterDistance() 
{
	type=0;
	if (MEASURE==0)
		DistanceA(1);
	else
		DistanceB(1);
   	Invalidate();
}

void CVCIPHView::OnOuterDistancea() 
{
	type=1;
	DistanceA(1);
   	Invalidate();
}

void CVCIPHView::OnFeatherArea()            //  Feather Area
{
	if (MEASURE==0)
		FeatherArea0();
	else
		FeatherArea1();
   	Invalidate();
}

void CVCIPHView::OnFeatherBlendA() 
{
	if (MEASURE==0)
		FeatherBlendA0();
	else
		FeatherBlendA1();
   	Invalidate();
}

void CVCIPHView::OnFeatherBlendB() 
{
	if (MEASURE==0) 
		FeatherBlendB0();
	else 
		FeatherBlendB1();
   	Invalidate();
}

void CVCIPHView::OnSetup() 
{
	CSetupDlg dlgSetup(this);

	dlgSetup.m_nMeasure     =MEASURE;
	dlgSetup.m_nLineDistance=LINEDISTANCE;
	dlgSetup.m_nAreaForm    =AREAFORM;
	if (dlgSetup.DoModal() != IDOK) {
		return;
	}
	MEASURE     =dlgSetup.m_nMeasure;
	LINEDISTANCE=dlgSetup.m_nLineDistance;
	AREAFORM    =dlgSetup.m_nAreaForm;
}

void CVCIPHView::DistanceC(int flag) 
{
	struct IMAGE_PARAMENTS Pt;
	HDC    hDCt;
	HBRUSH hBrush;
	HPEN   hPen;
	int    x,y,k,i,n,num,num1,num2,Dx,Dy;
	struct TAB *tabA,*tabB,*tab1,*tab2;   
    BYTE   **list;
 
  	DeleteDibs(pTempDibs);
	pTempDibs=CreateDibs(512,512,8);
	pTempDibs->SetDefaultPalette();
	GetImageParaments(&Pt,pTempDibs);
 	hDCt= GetMemDC(Pt.hBitmap);

	hPen=(HPEN)   GetStockObject((int) WHITE_PEN);
	hBrush=(HBRUSH) GetStockObject((int) WHITE_BRUSH); 
	SelectObject(hDCt,hPen);
	SelectObject(hDCt,hBrush);
	k=170;
	x=256;		y=256;
	PatBlt(hDCt,0,0,512,512,BLACKNESS);     //  画背景色
	Ellipse(hDCt,x-k,y-k,x+k,y+k);          //  画圆
   	ReleaseMemDC(hDCt); 

	tabA=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);
	tabB=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);
  
	Dx=Pt.ppl;		Dy=Pt.hei;
	n=1000;
	list =(BYTE**)malloc(Dy*sizeof(BYTE*));
	for (i=0;i<Dy;i++) list[i] =Pt.pBits+i*Dx;

	num=CreateTab(Pt.pBits,Pt.ppl,Pt.hei,tabA);  //  建立线段表

	num1=BorderDilation(tabB,tabA,num,8);   //  得区域外边界
	num =RegionCopy(tabA,tabB,num1);
 	for (i=0;i<num;i++) tabA[i].label=i+1;  //  设置表项序号
	num2=num;
	i=0;
	do {
		num1=num2;
		if (i%2==0) {
			tab1=tabA;	  tab2=tabB;
		}
		else {
			tab1=tabB;	  tab2=tabA;
		}
  		num2=BorderErosion(tab2,tab1,num1,8);      //  边界腐蚀
		if (flag==1)
			DistanceCorrectIC(tab2,num2,i+1);      //  根据曲率中心校正
		CopyLineTableData(list,tab2,num2,0,0,i+1); //  当前距离填入位图
    	i++;
	}
	while((num2)&&(i<n));
 
	free(tabA);  
	free(tabB);  
 	free(list);

	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pTempDibs);
}

void CVCIPHView::DistanceC1(int flag) 
{
	struct IMAGE_PARAMENTS Pt;
	HDC    hDCt;
	HBRUSH hBrush;
	HPEN   hPen;
	int    x,y,k,i,n,num,num1,num2,Dx,Dy;
	struct TAB *tabA,*tabB,*tab1,*tab2;   
    BYTE   **list;
	int    L,t,s;
	double d1,d2;
  	char   ch[20];
  	
  	DeleteDibs(pTempDibs);
	pTempDibs=CreateDibs(512,512,8);
	pTempDibs->SetDefaultPalette();
	GetImageParaments(&Pt,pTempDibs);

	tabA=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);
	tabB=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);
  
	Dx=Pt.ppl;		Dy=Pt.hei;
	n=1000;
	list =(BYTE**)malloc(Dy*sizeof(BYTE*));
	for (i=0;i<Dy;i++) list[i] =Pt.pBits+i*Dx;

	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (s=0;s<t;s++) {
			hDCt= GetMemDC(Pt.hBitmap);
			hPen=(HPEN)   GetStockObject((int) WHITE_PEN);
			hBrush=(HBRUSH) GetStockObject((int) WHITE_BRUSH); 
			SelectObject(hDCt,hPen);
			SelectObject(hDCt,hBrush);
			k=170;
			x=256;		y=256;
			PatBlt(hDCt,0,0,512,512,BLACKNESS);  //  画背景色
			Ellipse(hDCt,x-k,y-k,x+k,y+k);  //  画圆
   			ReleaseMemDC(hDCt); 
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d1=(float)L/t;

 	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (s=0;s<t;s++) {
			hDCt= GetMemDC(Pt.hBitmap);
			hPen=(HPEN)   GetStockObject((int) WHITE_PEN);
			hBrush=(HBRUSH) GetStockObject((int) WHITE_BRUSH); 
			SelectObject(hDCt,hPen);
			SelectObject(hDCt,hBrush);
			k=170;
			x=256;		y=256;
			PatBlt(hDCt,0,0,512,512,BLACKNESS);  //  画背景色
			Ellipse(hDCt,x-k,y-k,x+k,y+k);  //  画圆
   			ReleaseMemDC(hDCt); 

			num=CreateTab(Pt.pBits,Pt.ppl,Pt.hei,tabA);  //  建立线段表

			num1=BorderDilation(tabB,tabA,num,8);  //  得区域外边界
			num =RegionCopy(tabA,tabB,num1);
 			for (i=0;i<num;i++) tabA[i].label=i+1; //  设置表项序号
			num2=num;
			i=0;
			do {
				num1=num2;
				if (i%2==0) {
					tab1=tabA;	  tab2=tabB;
				}
				else {
					tab1=tabB;	  tab2=tabA;
				}
  				num2=BorderErosion(tab2,tab1,num1,8);      //  边界腐蚀
				if (flag==1)
					DistanceCorrectIC(tab2,num2,i+1);      //  根据曲率中心校正
				CopyLineTableData(list,tab2,num2,0,0,i+1); //  当前距离填入位图
//				CopyLineTableData(list,tab2,num2,0,0,-1); //  当前距离填入位图
    			i++;
			}
			while((num2)&&(i<n));
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d2=(float)L/t;
	sprintf(ch,"%5.2f 毫秒",d2-d1+0.005);
	MessageBox(ch,"运行时间",MB_OK);

 	free(tabA);  
 	free(tabB);  
 	free(list);
 	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pTempDibs);
}

void CVCIPHView::OnDistanceb() 
{
	if (MEASURE==0)
		DistanceC(1);                       //  根据曲率中心校正腐蚀
	else
		DistanceC1(1);
	Invalidate();
}

void CVCIPHView::OnDistancec() 
{
	if (MEASURE==0)
		DistanceC(0);                       //  仅腐蚀不校正
	else
		DistanceC1(0);
	Invalidate();
}

void CVCIPHView::DistanceD(int flag) 
{
	struct IMAGE_PARAMENTS Pt;
	HDC    hDCt;
	HBRUSH hBrush;
	HPEN   hPen;
	int    x,y,k,i,n,num,num1,num2,Dx,Dy;
	struct TAB *tabA,*tabB,*tab1,*tab2;   
    BYTE   **list;
 
  	DeleteDibs(pTempDibs);
	pTempDibs=CreateDibs(512,512,8);
	pTempDibs->SetDefaultPalette();
	GetImageParaments(&Pt,pTempDibs);
 	hDCt= GetMemDC(Pt.hBitmap);

	hPen=(HPEN)   GetStockObject((int) WHITE_PEN);
	hBrush=(HBRUSH) GetStockObject((int) WHITE_BRUSH); 
	SelectObject(hDCt,hPen);
	SelectObject(hDCt,hBrush);
	k=170;
	x=256;		y=256;
	PatBlt(hDCt,0,0,512,512,BLACKNESS);     //  画背景色
	Ellipse(hDCt,x-k,y-k,x+k,y+k);          //  画圆
   	ReleaseMemDC(hDCt); 

	tabA=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);
	tabB=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);
  
	Dx=Pt.ppl;		Dy=Pt.hei;
	n=1000;
	list =(BYTE**)malloc(Dy*sizeof(BYTE*));
	for (i=0;i<Dy;i++) list[i] =Pt.pBits+i*Dx;

	num=CreateTab(Pt.pBits,Pt.ppl,Pt.hei,tabA);  //  建立线段表

	num1=BorderErosion(tabB,tabA,num,8);    //  得区域内边界
	num =RegionCopy(tabA,tabB,num1);
 	for (i=0;i<num;i++) tabA[i].label=i+1;  //  设置表项序号
	num2=num;
	i=0;
	do {
		num1=num2;
		if (i%2==0) {
			tab1=tabA;	  tab2=tabB;
		}
		else {
			tab1=tabB;	  tab2=tabA;
		}
		if ((i%5)%2) k=8;
		else k=4;
		num2=BorderDilationCut(tab2,tab1,Dx,Dy,num1,k);  //  边界膨胀
		if ((flag==1)&&(k==4))
			DistanceCorrectOC(tab2,num2,i+1);      //  根据曲率中心校正
		CopyLineTableData(list,tab2,num2,0,0,i+1); //  当前距离填入位图
    	i++;
		if ((tab2[0].x2==0)&&(tab2[1].x1==Dx-1)&&
			(tab2[num2-2].x2==0)&&(tab2[num2-1].x1==Dx-1)) break;
	}
	while((num2)&&(i<n));
 
	free(tabA);  
	free(tabB);  
 	free(list);

	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pTempDibs);
}

void CVCIPHView::DistanceD1(int flag) 
{
	struct IMAGE_PARAMENTS Pt;
	HDC    hDCt;
	HBRUSH hBrush;
	HPEN   hPen;
	int    x,y,k,i,n,num,num1,num2,Dx,Dy;
	struct TAB *tabA,*tabB,*tab1,*tab2;   
    BYTE   **list;
	int    L,t,s;
	double d1,d2;
  	char   ch[20];
  	
  	DeleteDibs(pTempDibs);
	pTempDibs=CreateDibs(512,512,8);
	pTempDibs->SetDefaultPalette();
	GetImageParaments(&Pt,pTempDibs);

	tabA=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);
	tabB=(struct TAB *) malloc(sizeof(struct TAB)*MAX_DOTN);
  
	Dx=Pt.ppl;		Dy=Pt.hei;
	n=1000;
	list =(BYTE**)malloc(Dy*sizeof(BYTE*));
	for (i=0;i<Dy;i++) list[i] =Pt.pBits+i*Dx;

	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (s=0;s<t;s++) {
			hDCt= GetMemDC(Pt.hBitmap);
			hPen=(HPEN)   GetStockObject((int) WHITE_PEN);
			hBrush=(HBRUSH) GetStockObject((int) WHITE_BRUSH); 
			SelectObject(hDCt,hPen);
			SelectObject(hDCt,hBrush);
			k=170;
			x=256;		y=256;
			PatBlt(hDCt,0,0,512,512,BLACKNESS);  //  画背景色
			Ellipse(hDCt,x-k,y-k,x+k,y+k);  //  画圆
   			ReleaseMemDC(hDCt); 
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d1=(float)L/t;

 	t=1;
	do {
		t*=2;
		L=GetMilliSecond();
		for (s=0;s<t;s++) {
			hDCt= GetMemDC(Pt.hBitmap);
			hPen=(HPEN)   GetStockObject((int) WHITE_PEN);
			hBrush=(HBRUSH) GetStockObject((int) WHITE_BRUSH); 
			SelectObject(hDCt,hPen);
			SelectObject(hDCt,hBrush);
			k=170;
			x=256;		y=256;
			PatBlt(hDCt,0,0,512,512,BLACKNESS);   //  画背景色
			Ellipse(hDCt,x-k,y-k,x+k,y+k);  //  画圆
   			ReleaseMemDC(hDCt); 

			num =CreateTab(Pt.pBits,Pt.ppl,Pt.hei,tabA);  //  建立线段表

			num1=BorderErosion(tabB,tabA,num,8);  //  得区域内边界
			num =RegionCopy(tabA,tabB,num1);
 			for (i=0;i<num;i++) tabA[i].label=i+1;  //  设置表项序号
			num2=num;
			i=0;
			do {
				num1=num2;
				if (i%2==0) {
					tab1=tabA;	  tab2=tabB;
				}
				else {
					tab1=tabB;	  tab2=tabA;
				}
				if ((i%5)%2) k=8;
				else k=4;
				num2=BorderDilationCut(tab2,tab1,Dx,Dy,num1,k);  //  边界膨胀
				if ((flag==1)&&(k==4))
					DistanceCorrectOC(tab2,num2,i+1);      //  根据曲率中心校正
				CopyLineTableData(list,tab2,num2,0,0,i+1); //  当前距离填入位图
    			i++;
				if ((tab2[0].x2==0)&&(tab2[1].x1==Dx-1)&&
					(tab2[num2-2].x2==0)&&(tab2[num2-1].x1==Dx-1)) break;
			}
			while((num2)&&(i<n));
		}
		L=GetMilliSecond()-L;
	}
	while(L<250);
	d2=(float)L/t;
	sprintf(ch,"%5.2f 毫秒",d2-d1+0.005);
	MessageBox(ch,"运行时间",MB_OK);

 	free(tabA);  
 	free(tabB);  
 	free(list);
 	DeleteDibs(pWorkDibs);
	pWorkDibs=CopyDibs(pTempDibs);
}

void CVCIPHView::OnDistanced() 
{
	if (MEASURE==0)
		DistanceD(1);                       //  根据曲率中心校正膨胀
	else 
		DistanceD1(1);
	Invalidate();
}

void CVCIPHView::OnDistancee() 
{
	if (MEASURE==0)
		DistanceD(0);                       //  仅膨胀不校正
	else
		DistanceD1(0);
	Invalidate();
}